package aftersale

import (
	"context"
	"strconv"

	"mall/common/globalkey"
	"mall/common/modelx"
	"mall/common/moneyx"
	"mall/common/utils/pointy"
	"mall/service/backend/common/errorx"
	"mall/service/backend/common/i18n"
	"mall/service/order/model"
	"mall/service/order/rpc/internal/svc"
	"mall/service/order/rpc/internal/utils/errorhandler"
	"mall/service/order/rpc/types/order"

	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type BackendGetAfterSaleByIdLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBackendGetAfterSaleByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackendGetAfterSaleByIdLogic {
	return &BackendGetAfterSaleByIdLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *BackendGetAfterSaleByIdLogic) BackendGetAfterSaleById(in *order.AfterSaleIdReq) (*order.AfterSaleInfo, error) {
	// logrus.Info(fmt.Sprintf("IDReq: %+v", in))
	if in.Id == 0 {
		return nil, errorx.NewInvalidArgumentError(i18n.ValidationError)
	}

	res, err := l.svcCtx.AfterSaleRequest.FindOne(l.ctx, in.Id)
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}
	orderID := res.OrderID
	var media []*order.MediaInfo
	if in.WithMedia != nil && *in.WithMedia > 0 {
		subFilterMap := make(map[string]map[string][]any)
		subFilterMap[model.AttachmentRelationshipColumns.ObjectID] = map[string][]any{
			"in": {in.Id},
		}
		subFilterMap[model.AttachmentRelationshipColumns.ObjectType] = map[string][]any{
			"equalTo": {globalkey.AttachmentLogTypeAfterSale},
		}
		list, _, err := l.svcCtx.AfterSaleRequest.GetMedia(l.ctx, model.M{}, -1, subFilterMap)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		if len(list) > 0 {
			for _, v := range list {
				media = append(media, &order.MediaInfo{
					Uid:       &v.RelationshipID,
					Id:        pointy.GetPointer(strconv.FormatUint(v.AttachmentID, 10)),
					Thumbnail: pointy.GetPointer(uint32(v.AttachmentThumbnail)),
					Order:     pointy.GetPointer(uint32(v.AttachmentOrder)),
					Uri:       &v.AttachmentImageSource,
					Url:       &v.AttachmentImageURL,
					AltText:   &v.AttachmentImageAlt,
					MetaData:  &v.AttachmentImageMeta,
				})
			}
		}
	}

	var address []*order.OrderAddressInfo
	if orderID > 0 && in.WithAddress != nil && *in.WithAddress > 0 {
		subFilterMap := make(map[string]map[string][]any)
		subFilterMap[model.OrderAddressColumns.OrderID] = map[string][]any{
			"equalTo": {orderID},
		}
		list, _, err := l.svcCtx.Order.GetAddressList(l.ctx, model.M{}, -1, subFilterMap)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		if len(list) > 0 {
			for _, v := range list {
				address = append(address, &order.OrderAddressInfo{
					Id:         &v.OrderAddressID,
					OrderId:    &v.OrderID,
					UserId:     &v.UserID,
					Consignee:  &v.Consignee,
					Mobile:     &v.Mobile,
					Province:   &v.Province,
					City:       &v.City,
					District:   &v.District,
					Street:     &v.Street,
					Address:    &v.DetailedAddress,
					PostalCode: &v.PostalCode,
					RegionCode: &v.RegionCode,
					Label:      &v.Label,
					Status:     pointy.GetPointer(uint32(v.Status)),
				})
			}
		}
	}

	var payments []*order.OrderPaymentInfo
	if orderID > 0 && in.WithPayment != nil && *in.WithPayment > 0 {
		subFilterMap := make(map[string]map[string][]any)
		subFilterMap[model.OrderPaymentColumns.OrderID] = map[string][]any{
			"equalTo": {orderID},
		}
		list, _, err := l.svcCtx.Order.GetPaymentList(l.ctx, model.M{}, -1, subFilterMap)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		if len(list) > 0 {
			for _, v := range list {
				payments = append(payments, &order.OrderPaymentInfo{
					Id:      &v.OrderPaymentID,
					OrderId: &v.OrderID,
					No:      &v.No,
					Amount:  pointy.GetPointer(moneyx.FormatAmount(int64(v.Amount))),
					Type:    pointy.GetPointer(uint32(v.Type)),
					Name:    &v.Name,
					Code:    &v.Code,
					Status:  pointy.GetPointer(uint32(v.Status)),
					PaidAt:  pointy.GetPointer(modelx.FormatNullDotTime(v.PaidAt, "")),
				})
			}
		}
	}

	return &order.AfterSaleInfo{
		Id:               &res.ID,
		AfterSaleSn:      &res.AfterSalesSN,
		OrderId:          &res.OrderID,
		OrderItemId:      &res.OrderItemID,
		OrderSn:          &res.OrderSN,
		ProductId:        &res.ProductID,
		ProductCode:      &res.ProductCode,
		ProductSkuId:     &res.ProductSkuID,
		ProductSku:       &res.ProductSku,
		SkuThumbUrl:      &res.SkuImageURL,
		ProductSkuCode:   &res.ProductSkuCode,
		ProductTitle:     &res.ProductTitle,
		ProductPrice:     &res.ProductPrice,
		Quantity:         pointy.GetPointer(uint32(res.Quantity)),
		UserId:           &res.UserID,
		NickName:         &res.NickName,
		Mobile:           &res.Mobile,
		AfterSaleType:    pointy.GetPointer(uint32(res.AfterSaleType)),
		RefundType:       pointy.GetPointer(uint32(res.RefundType)),
		ReturnType:       pointy.GetPointer(uint32(res.ReturnType)),
		RefundAmount:     pointy.GetPointer(moneyx.FormatAmount(int64(res.RefundAmount))),
		RefundDetails:    pointy.GetPointer(modelx.FormatNullDotString(res.RefundDetails)),
		Remark:           pointy.GetPointer(modelx.FormatNullDotString(res.Remark)),
		ExpressSn:        &res.ExpressSN,
		ReasonForRefusal: &res.ReasonForRefusal,
		Status:           pointy.GetPointer(uint32(res.Status)),
		ProcessTime:      pointy.GetPointer(modelx.FormatNullDotTime(res.ProcessTime, "")),
		CreatedAt:        pointy.GetPointer(modelx.FormatTime(res.CreatedAt, "")),
		UpdatedAt:        pointy.GetPointer(modelx.FormatTime(res.UpdatedAt, "")),
		DeletedAt:        pointy.GetPointer(modelx.FormatNullDotTime(res.DeletedAt, "")),
		Addresses:        address,
		Media:            media,
		Payment:          payments,
	}, nil
}
